<?php
namespace App\Services;

//引入两个类
use App\Enum\CityEnableEnum;
use App\Enum\CityGpsEnum;
use App\Enum\RedisEnum;
use App\Enum\TravelEnum;
use App\Models\CityGpsModel;
use Illuminate\Support\Facades\Log;
use Location\Coordinate;
use Location\Polygon;
use Exception;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class RedisKeysService extends BaseService
{
    /**
     * redis 对象
     * @var null
     */
    private $redis = null;
    /**
     * 平台ID
     * @var string
     */
    private $platformId = 0;
    public function __construct()
    {
        $this->redis = app('redis.connection');
        $this->platformId = self::getPlatformId();
    }

    /**
     * 删除列表keys
     *
     * @param $userId
     * @param int $driverId
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws Exception
     */
    public function deleteOrderListKey($userId, int $driverId=0)
    {
        try {
            if ($this->platformId === TravelEnum::PLATFORM_DRIVER) $this->deleteDriverOrderListKey($userId);
            else {
                $this->deleteUserOrderListKey($userId);
                if(!empty($driverId)){
                    $this->deleteDriverOrderListKey($driverId);
                }
            }
        }catch (Exception $e){
            Log::error(sprintf("删除用户ordersKey失败，platformId=%d, E=%s",$this->platformId,$e->getMessage()));
            throw new Exception("追加订单列表key失败");
        }
    }

    /**
     * 追加订单列表key
     *
     * @param $userId
     * @param $key
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws Exception
     */
    public function addOrderListKey( $userId, $key )
    {
        try {
            if ($this->platformId === TravelEnum::PLATFORM_DRIVER) $this->addDriverOrderListKey($userId, $key);
            else $this->addUserOrderListKey($userId, $key);
        }catch (Exception $e){
            Log::error(sprintf("追加key到ordersKey失败,platformId=%d,input_key=%s，E=%s",$this->platformId,$key,$e->getMessage()));
            throw new Exception("追加订单列表key失败");
        }
    }

    /**
     * @param $userId
     * @param $key
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws Exception
     */
    public function addDriverWaitOrderListKey($userId, $key)
    {
        try {
            $redisKey = sprintf(RedisEnum::R_DRIVER_WAIT_ORDER_LIST_KEYS, $userId);
            $this->_appendOrderKey($redisKey,$key);
        }catch (Exception $e){
            Log::error(sprintf("追加key到WAIT ordersKey失败,platformId=%d,input_key=%s，E=%s",$this->platformId,$key,$e->getMessage()));
            throw new Exception("追加订单列表key失败");
        }
    }

    /**
     * @param $userId
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws Exception
     */
    public function deleteDriverWaitOrderListKey($userId)
    {
        try {
            $redisKey = sprintf(RedisEnum::R_DRIVER_WAIT_ORDER_LIST_KEYS, $userId);
            $this->_deleteOrderKey($redisKey);
        }catch (Exception $e){
            Log::error(sprintf("删除key到WAIT ordersKey失败,platformId=%d,，E=%s",$this->platformId,$e->getMessage()));
            throw new Exception("删除订单列表key失败");
        }
    }

    /**
     * 追加用户订单列表key
     *
     * @param $userId
     * @param $key
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function addUserOrderListKey($userId, $key)
    {
        $redisKey = sprintf(RedisEnum::R_USER_ORDER_LIST_KEYS, $userId);
        $this->_appendOrderKey($redisKey,$key);
    }

    /**
     * 删除司机订单列表keys
     *
     * @param $driverId
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function deleteDriverOrderListKey($driverId)
    {
        $redisKey = sprintf(RedisEnum::R_DRIVER_ORDER_LIST_KEYS, $driverId);
        $this->_deleteOrderKey($redisKey);
        $this->deleteDriverWaitOrderListKey($driverId);
    }

    /**
     * 删除用户订单列表keys
     *
     * @param $userId
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    private function deleteUserOrderListKey($userId)
    {
        $redisKey = sprintf(RedisEnum::R_USER_ORDER_LIST_KEYS, $userId);
        $this->_deleteOrderKey($redisKey);
    }

    /**
     * 追加司机 订单列表key
     *
     * @param $userId
     * @param $key
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    private function addDriverOrderListKey($userId, $key)
    {
        $redisKey = sprintf(RedisEnum::R_DRIVER_ORDER_LIST_KEYS, $userId);
        $this->_appendOrderKey($redisKey,$key);
    }

    /**
     * @param $baseKey
     * @param $inputKey
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws Exception
     */
    private function _appendOrderKey($baseKey,$inputKey)
    {
        try {
            // 取得redis 存储的key有哪些
            $keys = $this->redis->get($baseKey);
            if (empty($keys)) $keys = [];
            else $keys = json_decode($keys, true);
            // 插入、去重
            $keys[] = $inputKey;
            $keys = array_unique($keys);

            // 加入缓存
            $this->redis->set($baseKey, json_encode($keys, JSON_UNESCAPED_UNICODE), 'EX', RedisEnum::R_ORDER_LIST_TO);
        }catch (Exception $e){

            throw new Exception("追加key到ordersKey失败。");
        }
    }

    /**
     * 删除缓存Keys
     *
     * @param $baseKey
     * @return void
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     * @throws Exception
     */
    private function _deleteOrderKey($baseKey)
    {
        try {
            // 取得redis 存储的key有哪些
            $redisData = $this->redis->get($baseKey);
            if( !empty($redisData) ){
                $keys = json_decode($redisData,true);
                $keys[] = $baseKey;
                foreach( $keys as $key )
                    $this->redis->del($key);
            }
        }catch (Exception $e){
            throw new Exception($e->getMessage());
        }
    }
}
